#pragma once

#include "../DefinesCore.hpp"
#include <vector>
#include <string>
#include <iostream>
#include <sstream>

#include "cybertron/core/UtilPath.hpp"
#include "cybertron/core/UtilFile.hpp"
#include "cybertron/core/UtilProcess.hpp"

CYBERTRON_BEGIN

/**
 * @class UtilPython
 * @brief The Python related utilities
 *
 */
class UtilPython
{
public:
    /** @brief Call a python process and execute a python script
	 * @param[in] pythonScriptName The python script need to be executed
	 * @param[in] pythonScriptPath The working directory to execute the python script 
     * @param[in] args Optional arguments transfers to the script.
	 * @return The return value from the python process, return UINT32_MAX means the process is failed to start.
     */
	template<typename... Args>
	CybertronCoreAPI 
        static uint32_t runPythonCmd(
            const std::string pythonScriptName,
            const std::string pythonScriptPath,
            Args... args/*optional args*/)
    {
        uint32_t returnValue = UINT32_MAX;
        if (UtilFile::exist(
            UtilPath::combine(pythonScriptPath, pythonScriptName)))
        {
            std::vector<std::string> parameters;
            addParameter(parameters, pythonScriptName, args...);
            std::vector<std::string> envs;
            ProcessHandle pHandle;

            logEvent("Python task is starting...");
            bool res = UtilProcess::start("python",
                pythonScriptPath, parameters, pHandle, envs, &returnValue, true);
            if (!res)
            {
                logError("Python task is failed to start");
            }
        }
        return returnValue;
    }

private:
    template<typename T>
    static void addParameter(std::vector<std::string>& strs, T& arg)
    {
        std::stringstream s;
        s << arg;
        strs.push_back(s.str());
    }
    template<typename T, typename... Args>
    static void addParameter(std::vector<std::string>& strs, T& arg, Args... args)
    {
        std::stringstream s;
        s << arg;
        strs.push_back(s.str());
        addParameter(strs, args...);
    }

};

CYBERTRON_END
